//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __CKPROCESS_H_
#define __CKPROCESS_H_

#include <elasys_server.h>
#include <interlocked.h>
#include <linknode.h>

class CProcess : public IProcess,
                 public IMemoryTrace
{
// Interface functions
//
public:
    CARAPI_(PInterface) Probe(
        /* [in]  */ REIID riid);

    CARAPI_(UInt32) AddRef(void);

    CARAPI_(UInt32) Release(void);

    CARAPI Aggregate(
        /* [in] */ AggregateType type,
        /* [in] */ PInterface pObject);

    CARAPI GetDomain(
        /* [out] */ PInterface *ppObject);

    CARAPI Start(
        /* [in] */ WString wsName,
        /* [in] */ WString wsArgs);

    CARAPI Kill();

    CARAPI WaitForExit(
        /* [in] */ Millisecond32 ms,
        /* [out] */ WaitResult *pResult);

    CARAPI IsAlive(
        /* [out] */ Boolean *pIsAlive);

    CARAPI SetPriorityRank(
        /* [in] */ ThreadPriorityRank priorityRank);

    CARAPI GetPriorityRank(
        /* [out] */ ThreadPriorityRank * pPriorityRank);

    CARAPI SetThreadPoolCapacity(
        /* [in] */ Int32 capacity);

    CARAPI GetThreadPoolState(
        /* [out] */ Int32 * pCapacity,
        /* [out] */ Int32 * pThreads);

    CARAPI GetAllThreads(
        /* [out] */ IObjectEnumerator ** ppThreads);

    CARAPI GetAllModules(
        /* [out] */ IObjectEnumerator ** ppModules);

    CARAPI GetModuleByName(
        /* [in] */ WString wsName,
        /* [out] */ IModule * * ppModule);

    CARAPI GetModuleByAddress(
        /* [in] */ Address address,
        /* [out] */ IModule * * ppModule);

    CARAPI GetId(
        /* [out] */ ProcessId * pPid);

    CARAPI GetStartInfo(
        /* [out] */ WStringBuf * pName,
        /* [out] */ WStringBuf * pArgs);

    CARAPI GetExitCode(
        /* [out] */ ExitCode * pExitCode);

    CARAPI GetStartTime(
        /* [out] */ SystemTime * pTime);

    CARAPI GetExitTime(
        /* [out] */ SystemTime * pTime);

    CARAPI GetProcessorTimes(
        /* [out] */ Millisecond32 * pUserTime,
        /* [out] */ Millisecond32 * pPrivilegedTime);

    CARAPI GetMemorySizes(
        /* [out] */ Int32 * pPrivateVirtualMemorySize,
        /* [out] */ Int32 * pSharedVirtualMemorySize,
        /* [out] */ Int32 * pPrivatePhysicalMemorySize,
        /* [out] */ Int32 * pSharedPhysicalMemorySize);

    // IMemoryTrace
    CARAPI SetTraceArgs(
        /* [in] */ Int32 wcArgId,
        /* [in] */ Int32  index,
        /* [in] */ Address watchAddress);

    CARAPI SetTraceDebug(
        /* [in] */ Boolean bDebug);

    CARAPI IsTraceDebug(
        /* [out] */ Boolean *pDebug);

public:
    static ECode New(
        /* [out] */ IProcess ** ppProcess);

public:
    CProcess():m_processId(-1),
            m_moduleListState(0),
            m_moduleListLock(NULL),
            m_threadListState(0),
            m_threadListLock(NULL) {}

    virtual ~CProcess();

    ECode Helper_LoadModule(
        /* [in] */ WString name,
        /* [in] */ ModuleLoadFlags flags,
        /* [out] */ IModule ** ppModule);

    void  Helper_ExitCurrent(
        /* [in] */ ExitCode exitCode);

    void  Helper_AttachThread(DLinkNode *);
    void  Helper_DetachThread(DLinkNode *);
    void  Helper_AttachModule(DLinkNode *);
    void  Helper_DetachModule(DLinkNode *);

private:
    ECode Constructor();

private:
    ProcessId  m_processId;
    SystemTime m_startTime;

    WStringBuf_<MAXIMUM_FULL_PATH_LENGTH> m_name;
    WStringBuf_<MAXIMUM_ARGS_LENGTH>      m_args;

    DLinkNode m_moduleList;
    Int32     m_moduleListState;
    PVoid     m_moduleListLock;

    DLinkNode m_threadList;
    Int32     m_threadListState;
    PVoid     m_threadListLock;

private:
    Interlocked m_Refs;
};

#endif

